// ignore_for_file: avoid_print

import 'dart:async';
import 'dart:convert';

import 'package:flujs/flujs.dart';
import 'package:flujs_jsc/jsc.dart' as jsc;
import 'package:flujs_qjs/qjs.dart' as qjs;
import 'package:flutter_test/flutter_test.dart';

void main() {
  itf(JSFRuntime rt) async {
    var ctx = rt.newContext()..loadExtension();
    ctx.addInterface('run', (args) {
      var sb = StringBuffer();
      sb.write('[run] Called! $args');
      for (var v in args) {
        sb.write('\t [run] ${v.runtimeType}');
      }
      sb.writeln();
      print(sb.toString());
    });
    ctx.eval('''
run(undefined);
run(null);
run(true, false);
run('test');
run(123);
// run(({a: 1, b: 2}));
// run(new Date());

// let m = new Map();
// let s = new Set();
// s.add(1);
// m.set('1', 1);
// run(m);
// run(s);

// run([1, 2,3]); // not support
// TODO: [] {} 互相嵌套 // 其他的类型可以 JSON.stringify 转换
''');
  }

  itfAync(JSFRuntime rt) async {
    var ctx = rt.newContext()..loadExtension();
    ctx.addInterface('runAsync', (args) async {
      var completer = Completer<int>();
      Timer(const Duration(seconds: 1), () {
        completer.complete(1);
      });
      return completer.future;
    });
    ctx.eval('''
async function t() {
  const r = await runAsync();
  console.log(r)
}
''');
    final tFunc = ctx.globalObject.getProperty('t');
    await ctx.runPromise(tFunc);
  }

  test('itf_jsc', () async {
    var rt = jsc.getJSFRuntime();
    itf(rt);
  });
  test('itf_qjs', () async {
    var rt = qjs.getJSFRuntime();
    itf(rt);
  });

  test('eval_convert_qjs', () {
    var rt = qjs.getJSFRuntime();
    var ctx = rt.newContext()..loadExtension();
    var ov = ctx.eval('''
JSON.stringify({k: 1, v: 2})
''');
    expect(ov.isString(), true);
    expect(ov.isObject(), false);
    expect(ov.isDate(), false);
    print(jsonDecode(ov.toStringCopy() ?? 'empty'));
    // print('isObject: ${ov.isObject()} ${ov.toDart()} ${ov.isDate()}');
  });

  test('itf_async_qjs', () async {
    var rt = qjs.getJSFRuntime();
    itfAync(rt);
  });
  test('itf_async_jsc', () async {
    var rt = jsc.getJSFRuntime();
    itfAync(rt);
  });
}
